package com.weirong.smartvault.backservice.util.common;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * 于2017/12/3由 KFEB4 创建 .
 */
public class ListTool {
    public static <T> List<T> moveToTop(List<T> list,T obj){
        if (obj== null)
            return list;
        if (list.indexOf(obj)>=0) {
            list.remove(obj);
            list.add(0, obj);
        }
        return list;
    }
    public static<T> List<T> cast(Iterable<?> list, Class<T> gClass) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        List<T> goal = new ArrayList<>();
        for(Object t :list){
            Class returnTypeClass = t.getClass();
            Constructor cons;
            try {
                cons = gClass.getConstructor(Object.class);
            }catch (NoSuchMethodException e){
                cons = gClass.getConstructor(returnTypeClass);
            }
            goal.add((T) cons.newInstance(t)) ;
        }
        return goal;
    }

    public static <T> List<T>  castList(Iterable<?> list,Class<T> gclass){
        List<T> goal = new ArrayList<>();
        for(Object t:list){
            goal.add((T)t);
        }
        return goal;
    }
    public static List<List> divideByKeys(List list,String[] paramNames) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        List<List> res = new ArrayList<>();
        List<List> tr = new ArrayList<>();
        tr.add(list);
        for (String param:paramNames){
            res.clear();
            for (List l:tr){
                Map<Object, List> t = divideByKey(l,param);
                res.addAll(t.values());
            }
            tr.clear();
            tr.addAll(res);
        }
        return res;
    }

    public static <T> List<T>  filter(List<T> list, Func func, Object value) {
        List<T> res = new ArrayList<>();
        for(T t:list){
            if(value.equals(func.cal(t)))
                res.add(t);
        }
        return res;
    }
    public static<T> Map<Object, List<T>> divideByKey(Iterable<T> list, String paramName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Map<Object,List<T>> res = new HashMap<>();
        for (T obj:list){
            Object key = ReflectTool.runMethod(obj,paramName);
            if (!res.containsKey(key)){
                res.put(key, new ArrayList<>());
            }
            res.get(key).add(obj);
        }
        return res;
    }
    public static<T> List<T> collect(List<T> list,Func<T> func){
        List<T> res = new ArrayList<>();
        for(T t:list){
            res.addAll((Collection<? extends T>)func.cal(t));
        }
        return res;
    }
    public static<T> Map<Object, List<T>> divideByKey(Iterable<T> list, Func<T> func){
        Map<Object,List<T>> res = new HashMap<>();
        for (T obj:list){
            Object key = func.cal(obj);
            if (!res.containsKey(key)){
                res.put(key, new ArrayList<>());
            }
            res.get(key).add(obj);
        }
        return res;
    }
    public static<T> List map(List<T> list, Func<T> func){
        List res = new ArrayList<>();
        for (T obj :list){
            res.add(func.cal(obj));
        }
        return res;
    }
}
